const { Order, Car, User, Dictionary } = require('../models');
const sequelize = require('sequelize');
const { Op, fn, col } = require('sequelize');
const dayjs = require('dayjs');

class OrderService {
	static injector(ctn) {
		return [
			ctn.make('varal.app')
		]
	}
	constructor(app) {
		this.app = app;
	}

	async get(filter, page = 1, page_size = 20, sorter) {
		const {
			out_trade_no, contact, phone, company, uscc, category_id, work_id,
			order_start_time,
			order_end_time,
			is_cart = 0,
			is_draft = 0,
			user_id,
			id,

			car_name,
			status,
			pay_status,
			tree_parent_fullname,
			team_parent_fullname,
			agency_fullname
		} = filter;
		const where = {};
		if (out_trade_no) where['out_trade_no'] = { [Op.like]: `%${out_trade_no}%` };
		if (contact) where['contact'] = { [Op.like]: `%${contact}%` };
		if (contact) where['contact'] = { [Op.like]: `%${contact}%` };
		if (phone) where['phone'] = { [Op.like]: `%${phone}%` };
		if (company) where['company'] = { [Op.like]: `%${company}%` };
		if (uscc) where['uscc'] = { [Op.like]: `%${uscc}%` };
		if (user_id) where['user_id'] = user_id;
		if (id) where['id'] = { [Op.in]: String(id).split(',') };

		//pay_status,status为数值型，当传值为0时，if (0)为false

		//空字符、null、空格和undefined转为数值型会变为NaN，再通过isNaN来判断。字符0、1
		if (!isNaN(parseInt(pay_status))) where['pay_status'] = pay_status;
		if (!isNaN(parseInt(status))) where['status'] = status;

		where['is_cart'] = is_cart;
		where['is_draft'] = is_draft;

		if (order_start_time) where['create_time'] = { [Op.between]: [order_start_time, order_end_time] };
		if (work_id || category_id) {
			where['$car.category_id$'] = {
				[Op.and]: [
					category_id ? category_id : null,
					work_id ? { [Op.in]: sequelize.literal(`(select category_id from app_car_category_work where work_id='${work_id}')`) } : null
				].filter((d) => d)
			}
		}

		if (car_name) where['$car.name$'] = { [Op.like]: `%${car_name}%` };
		if (tree_parent_fullname) where['$buyer.tree_parent.fullname$'] = { [Op.like]: `%${tree_parent_fullname}%` };
		if (team_parent_fullname) where['$buyer.team_parent.fullname$'] = { [Op.like]: `%${team_parent_fullname}%` };
		if (agency_fullname) where['$agency.fullname$'] = { [Op.like]: `%${agency_fullname}%` };

		const { count: total, rows: data } = await Order.findAndCountAll({
			where,
			include: [{
				model: Car,
				as: 'car',
				attributes: ['name', 'version', 'description', 'is_license', 'thumb', 'price', 'award', 'commission', 'bonus'],
				/*
				include: [
					{
						model: Dictionary,
						as: 'category',
						attributes: ['name'],

						include: [{
							model: Dictionary,
							as: 'works',
							attributes: ['name']
						}]
					}
				]
				*/
			}, {
				model: User,
				as: 'buyer',
				attributes: ['fullname', 'nickname', 'username', 'phone'],
				include: [{
					model: User,
					as: 'tree_parent',
					attributes: ['fullname']
				}, {
					model: User,
					as: 'team_parent',
					attributes: ['fullname']
				}]
			}, {
				model: User,
				as: 'agency',
				attributes: ['fullname']
			}],

			offset: (page - 1) * page_size,
			limit: page_size * 1,
			order: sorter || [
				['id', 'desc']
			]
		});

		return {
			data,
			total
		}
	}

	async info(where) {
		return await Order.findOne({
			where,
			include: [{
				model: Car,
				as: 'car',
				include: [
					{
						model: Dictionary,
						as: 'category',
						attributes: ['name'],

						include: [{
							model: Dictionary,
							as: 'works',
							attributes: ['name']
						}]
					}
				]
			}]
		});
	}

	async save(params) {
		['create_time', 'update_time', 'delete_time'].forEach((d) => {
			delete params[d];
		});

		const { id } = params;

		if (id) {
			const data = await Order.findOne({
				where: { id },
				include: ['car']
			});

			//计算总价
			params.total_price = data.price * (params.quantity || data.quantity || 1) + parseFloat(data.car_model_price || 0) - parseFloat(data.coupon_price || 0) - parseFloat(data.discount || 0);

			//完结
			if (params.status === 3) {
				if (data.car.is_license && !data.car_license) {
					throw '当前车辆订单必须上传行驶证才可以完结';
				}

				//结算
				//this.app.service('JournalService').dispatch(data.out_trade_no);
			}

			return Order.update(params, {
				where: { id }
			})
		} else {
			return Order.create(params);
		}
	}

	async delete(id) {
		return Order.destroy({
			where: {
				id: { [sequelize.Op.in]: String(id).split(',') }
			}
		});
	}
}

exports = module.exports = OrderService;
